package com.base.cn.platform.os.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 自定义返回结果处理器，该返回结果处理器，是只为了删除值为null的结果属性
 * @author s.li
 * @date 2019/01/18
 */
@Slf4j
public class MyHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    @Override
    public boolean supportsReturnType(MethodParameter methodParameter) {
        Class cls = methodParameter.getContainingClass();
        return cls.isAnnotationPresent(RestController.class);
    }
    @Override
    public void handleReturnValue(Object returnValue, MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest) throws Exception {
        modelAndViewContainer.setRequestHandled(true);
        HttpServletRequest request = getNativeRequest(nativeWebRequest);
        HttpServletResponse response = getNativeResponse(nativeWebRequest);
        writeWithMessageConverters(returnValue, methodParameter, request, response);
    }

    /**
     * 重新定义输出结果
     * @param returnValue 返回结果
     * @param methodParameter
     * @param request
     * @param response
     */
    private void writeWithMessageConverters(Object returnValue,
                                            MethodParameter methodParameter,
                                            HttpServletRequest request,
                                            HttpServletResponse response) {
        //这里用JSONObject，而不用Gson是因为gson相互转换时整数会变成小数点
        JSONObject jsonObject = (JSONObject) JSON.toJSON(returnValue);
        Object entity = jsonObject.get("entity");//获取返回结果
        try{
            if(entity !=null){
                if(entity instanceof JSONObject){
                    this.handleJSONObject((JSONObject)entity);
                }else if(entity instanceof JSONArray){
                    this.handleJSONArray((JSONArray)entity);
                }
            }
            //重新输出处理后的结果
            String encoding = request.getCharacterEncoding();
            response.setCharacterEncoding(encoding);
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(jsonObject.toJSONString());
            response.getWriter().flush();
        }catch (Exception e){
            log.error("writeWithMessageConverters()--error",e);
        }
    }

    private HttpServletRequest getNativeRequest(NativeWebRequest webRequest){
        return webRequest.getNativeRequest(HttpServletRequest.class);
    }

    private HttpServletResponse getNativeResponse(NativeWebRequest webRequest){
        return webRequest.getNativeResponse(HttpServletResponse.class);
    }

    /**
     * 处理 JSONObject
     * @param _jsonObject
     */
    private void handleJSONObject(JSONObject _jsonObject){
        List keyList = new ArrayList();
        _jsonObject.forEach((k,v)->{
            if(v==null){
                keyList.add(k);//删除值为空的属性
            }else{
                if(v instanceof JSONObject){
                    this.handleJSONObject((JSONObject) v);
                }else if(v instanceof JSONArray){
                    this.handleJSONArray((JSONArray)v);
                }else if(v instanceof Date){
                    _jsonObject.put(k,simpleDateFormat.format((Date)v));
                }
            }
        });
        if(ObjectUtils.isNotEmpty(keyList)){
            keyList.forEach(k->{
                _jsonObject.remove(k);
            });
        }
    }

    /**
     * 处理 JSONArray
     * @param jsonArray
     */
    private void handleJSONArray(JSONArray jsonArray){
        jsonArray.forEach(object->{
            if(object instanceof  JSONObject){
                this.handleJSONObject((JSONObject) object);
            }else if(object instanceof JSONArray){
                this.handleJSONArray((JSONArray) object);
            }
        });
    }

}
